/**
 * 
 */
package logic;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import jpa_objects.Branch;
import jpa_objects.Business;
import jpa_objects.City;
import jpa_objects.Comment;
import jpa_objects.Discount;
import jpa_objects.Event;
import jpa_objects.Event_report;
import jpa_objects.Feedback;
import jpa_objects.Instructor;
import jpa_objects.Message;
import jpa_objects.Player;
import jpa_objects.Review;
import jpa_objects.Sport;
import jpa_objects.Sport_calification;
import jpa_objects.User;
import jpa_objects.User_report;
import json_objects_received.JaxCommonClases;
import json_objects_received.JaxSport;
import json_objects_send.Basic_User;
import json_objects_send.CommonUser;
import json_objects_send.Conversation;
import json_objects_send.Event_Info;
import json_objects_send.Full_Business;
import json_objects_send.Full_Instructor;
import json_objects_send.Full_Player;
import json_objects_send.Full_User;
import json_objects_send.JSON_Branch;
import json_objects_send.JSON_Discount;
import json_objects_send.JSON_Message;
import json_objects_send.JSON_business;
import json_objects_send.JSON_comment;
import json_objects_send.JSON_event;
import json_objects_send.JSON_instructor;
import json_objects_send.JSON_notification;
import json_objects_send.JSON_player;
import json_objects_send.JSON_review;
import json_objects_send.JSON_sport_calification;

import persistence.DBCommonAlter;
import persistence.DBCommonConsult;

/**
 * @author Alejandro Casas
 *
 */
public class CluvieMain {





	public CluvieMain() {

	}

	public List<String> getSports() {

		DBCommonConsult dbc=new DBCommonConsult();
		List<Sport> list=dbc.getSports();

		List<String> r=new ArrayList<String>();
		for (Sport sport : list) {
			r.add(sport.getName()+"/"+sport.getWraper());
		}

		return r;
	}

	public List<String> getCities(String country) {
		List<City> list= (new DBCommonConsult()).getCities(country);
		List<String> r=new ArrayList<String>();
		for (City city : list) {
			r.add(city.getName());
		}
		return r;
	}

	public Event_Info getEventInfo(long id,String viewer) {
		DBCommonConsult conexion = new DBCommonConsult();
		Event e=(conexion).getEvent(id);
		return new Event_Info(e.getId(), e.getAddress(), e.getDescription(),
				e.getEnding_date(), e.getLat(), e.getLng(), e.getOpenings(), 
				e.getPicture(), e.isPrivacy(), e.getStarting_date(), e.getTitle(),
				convertComments(e.getComments()), sportToString(e.getSports()),e.getCity().getName() , 
				convertPlayers(e.getRegistered(), viewer),convertPlayers(e.getApplicants(), viewer), 
				e.getCity().getCountry(), e.getOwnersMail(), e.getOwnersName(),
				getFriendsRegisteredInEvent(viewer, e));
	}

	public List<Basic_User> getEventParticipationRequests(long id) 
	{

		Event e=(new DBCommonConsult()).getEvent(id);
		List<Player> applicants=e.getApplicants();
		List<Basic_User> ap=new ArrayList<Basic_User>();
		String ownerMail = e.getOwnersMail();


		for (Player p : applicants) 
		{

			ap.add(new Basic_User(p.getName(), p.getMail(), p.getMiniPicture(), p.getCountry(),
					p.getCity().getName(),getFriendsInCommon(p.getMail(), ownerMail)));
		}
		return ap;
	}

	public boolean acceptEventParticipationRequest(long eventId,String mail, String nameFrom) {
		DBCommonConsult dbc=new DBCommonConsult();
		Event e=dbc.getEvent(eventId);
		List<Player> app=e.getApplicants();
		List<Player> participants=e.getRegistered();
		for (Player ap: app) {
			if(ap.getMail().equals(mail))
			{
				Player p=dbc.getPlayer(mail);
				List<Event> l=p.getEvent_history();
				l.add(e);
				app.remove(ap);
				e.setApplicants(app);
				participants.add(p);
				sendMessage("sender@cluvie.com",mail,"Te han aceptado en un evento!",
						"Has sido aceptado en el evento "+e.getTitle(),nameFrom,"");
				DBCommonAlter dba=(new DBCommonAlter());
				dba.saveUser(p, DBCommonAlter.UPDATE_USER);
				return dba.saveEvent(e,DBCommonAlter.UPDATE_EVENT);
			}
		}
		return false;
	}

	public boolean sendMessage(String mailFrom, String mailTo, String title,
			String message, String nameFrom,String miniPictureFrom) {
		DBCommonConsult dbc=new DBCommonConsult();
		DBCommonAlter dba=new DBCommonAlter();
		User from=dbc.getUser(mailFrom,DBCommonConsult.CONVERSATIONS);
		User to=dbc.getUser(mailTo,DBCommonConsult.CONVERSATIONS);
		Message m=new Message(""+(new Timestamp(( new java.util.Date()).getTime())),
				mailFrom, message, title,mailTo,nameFrom,miniPictureFrom);
		List<Message> sent=from.getSent();
		sent.add(m);
		from.setSent(sent);
		List<Message> received=to.getReceived();
		received.add(m);
		to.setReceived(received);
		dba.saveUser(from,DBCommonAlter.UPDATE_USER);
		dba.saveUser(to,DBCommonAlter.UPDATE_USER);
		return true;

	}

	public boolean rejectEventParticipationRequest(long eventId, String mail, String nameFrom) {
		DBCommonConsult dbc=new DBCommonConsult();
		Event e=dbc.getEvent(eventId);
		List<Player> app=e.getApplicants();

		for (Player ap: app) {
			if(ap.getMail().equals(mail))
			{
				app.remove(ap);
				e.setApplicants(app);
				sendMessage("sender@cluvie.com",mail,"No has sido aceptado en "+e.getTitle(),
						"No has sido aceptado en el evento "+e.getTitle(), nameFrom,"");
				return (new DBCommonAlter()).saveEvent(e,DBCommonAlter.UPDATE_EVENT);
			}
		}
		return false;
	}

	public List<Basic_User> getEventRegisteredParticipants(long eventId,String viewer) 
	{

		Event e=(new DBCommonConsult()).getEvent(eventId);
		List<Player> registered=e.getRegistered();
		List<Basic_User> ap=new ArrayList<Basic_User>();



		for (Player p : registered) 
		{
			ap.add(new Basic_User(p.getName(), p.getMail(), p.getMiniPicture(), p.getCountry(),
					p.getCity().getName(),getFriendsInCommon(p.getMail(), viewer)));
		}
		return ap;
	}

	/**
	 * 1. va buscando las conversaciones en sent y luego en recieved
	 *  y guarda si no estaba antes. Si estaba compara las fechas
	 * de los mensajes, y si la fecha es mas reciente, cambia en el objeto
	 * la fecha el mensaje y el remitente.
	 * @param mail
	 * @return
	 */
	public List<Conversation> getUserConversations(String mail) {
		DBCommonConsult dbc=new DBCommonConsult();
		User us=dbc.getUser(mail,DBCommonConsult.CONVERSATIONS);
		List<Message> sent=us.getSent();
		List<Message> recieved=us.getReceived();
		List<Conversation> conversations=new ArrayList<Conversation>();
		for (Message message : recieved) {
			User u=dbc.getUser(message.getMailFrom(),DBCommonConsult.LAZY);
			boolean exists=false;
			for (Conversation conversation : conversations) {
				if(conversation.getSenderMail().equals(message.getMailFrom()))
				{
					if(conversation.compareByDate(message.getDate())<0)
					{
						conversation.setDate(message.getDate());
						conversation.setLastMessage(message.getMessage());
						conversation.setSenderMiniPicture(u.getMiniPicture());
						conversation.setSenderName(u.getName());
					}
					exists=true;
					break;
				}
			}
			if(!exists)
			{
				conversations.add(new Conversation(message.getDate(),
						u.getMiniPicture(),
						message.getMailFrom(),u.getName() , message.getMessage()));
			}
		}
		for (Message message : sent) {
			User u=dbc.getUser(message.getMailFrom(),DBCommonConsult.LAZY);
			boolean exists=false;
			for (Conversation conversation : conversations) {
				if(conversation.getSenderMail().equals(message.getMailFrom()))
				{
					if(conversation.compareByDate(message.getDate())<0)
					{
						conversation.setDate(message.getDate());
						conversation.setLastMessage(message.getMessage());
						conversation.setSenderMiniPicture(u.getMiniPicture());
						conversation.setSenderName(u.getName());
					}
					exists=true;
					break;
				}
			}
			if(!exists)
			{
				conversations.add(new Conversation(message.getDate(),
						u.getMiniPicture(),
						message.getMailFrom(),u.getName() , message.getMessage()));
			}
		}
		return conversations;
	}

	public List<JSON_Message> getUserMessages(String mailUser,String mailWith) {
		DBCommonConsult dbc=new DBCommonConsult();
		List<Message> sent=dbc.getUserMessagesWith(mailUser,mailWith);
		List<JSON_Message> r=new ArrayList<JSON_Message>();

		for (Message message : sent) 
		{

			r.add(new JSON_Message(message.getDate(), message.getMailFrom(), message.getMessage(),
					true, message.getId(), message.getNameFrom(),message.getMiniPictureFrom()));
		}
		return r;
	}

	public Basic_User getUserBasicInfo(String mail, String viewer) {
		System.out.println("bbbbbbbbbbbbb");
		System.out.println(mail);
		System.out.println("bbbbbbbbbbbbb");
		DBCommonConsult dbc=new DBCommonConsult();

		User a = dbc.getUser(mail,DBCommonConsult.LAZY);
		if(a!=null)
		{
		return new Basic_User(a.getName(),a.getMail(),a.getMiniPicture(),
				a.getCountry(),a.getCity().getName(), getFriendsInCommon(mail,viewer));
		}
		else
		{
			return new Basic_User("","","",
					"","", null);
		}
	}

	public boolean setStatus(String mail, String status) {
		DBCommonConsult dbc=new DBCommonConsult();

		User u=dbc.getUser(mail,DBCommonConsult.CONVERSATIONS);
		u.setStatus(status);
		(new DBCommonAlter()).saveUser(u,DBCommonAlter.UPDATE_USER);
		return true;
	}

	public List<JSON_review> getUserReviews(String mail,String viewer) {
		DBCommonConsult dbc=new DBCommonConsult();

		User u=dbc.getUser(mail,DBCommonConsult.REVIEWS);
		return convertReviews(u.getReviews(), viewer);
	}

	public boolean reportUser(String mailReported, String mailReporter,
			String message) {
		User_report r=new User_report(""+(new Timestamp(( new java.util.Date()).getTime())), mailReported, mailReporter, message);
		return (new DBCommonAlter()).saveReport(r);
	}

	public boolean follow(String mailFollowed, String mailFollower) {
		DBCommonConsult dbc=new DBCommonConsult();
		DBCommonAlter dba=new DBCommonAlter();
		User b=dbc.getUser(mailFollowed,DBCommonConsult.FOLLOW_FRIENDS);
		User u=dbc.getUser(mailFollower,DBCommonConsult.FOLLOW_FRIENDS);
		if(b instanceof Business)
		{
			List<Business> l=u.getFollowing_businesses();
			l.add((Business)b);
			u.setFollowing_businesses(l);

			List<User> a=((Business) b).getFollowers();
			a.add(u);
			dba.saveUser(b,DBCommonAlter.UPDATE_USER);
			dba.saveUser(u,DBCommonAlter.UPDATE_USER);
		}
		else if(b instanceof Instructor)
		{
			List<Instructor> l=u.getFollowing_instructors();
			l.add((Instructor)b);
			u.setFollowing_instructors(l);
			List<User> a=((Business) b).getFollowers();
			a.add(u);
			dba.saveUser(b,DBCommonAlter.UPDATE_USER);
			dba.saveUser(u,DBCommonAlter.UPDATE_USER);

		}
		else
		{
			return false;
		}
		return true;
	}

	public boolean unfollow(String mailFollowed, String mailFollower) {
		DBCommonConsult dbc=new DBCommonConsult();
		DBCommonAlter dba=new DBCommonAlter();
		User b=dbc.getUser(mailFollowed,DBCommonConsult.FOLLOW_FRIENDS);
		User u=dbc.getUser(mailFollower,DBCommonConsult.FOLLOW_FRIENDS);
		if(b instanceof Business)
		{
			List<Business> l=u.getFollowing_businesses();
			l.remove((Business)b);
			u.setFollowing_businesses(l);

			List<User> a=((Business) b).getFollowers();
			a.remove(u);
			dba.saveUser(b,DBCommonAlter.UPDATE_USER);
			dba.saveUser(u,DBCommonAlter.UPDATE_USER);
		}
		else if(b instanceof Instructor)
		{
			List<Instructor> l=u.getFollowing_instructors();
			l.remove((Instructor)b);
			u.setFollowing_instructors(l);
			List<User> a=((Business) b).getFollowers();
			a.remove(u);
			dba.saveUser(b,DBCommonAlter.UPDATE_USER);
			dba.saveUser(u,DBCommonAlter.UPDATE_USER);

		}
		else
		{
			return false;
		}
		return true;
	}

	public boolean writeReview(String mailFrom, String mailTo, json_objects_received.JaxSport sport,
			int calification, String title, String message, String nameFrom) {
		DBCommonConsult dbc=new DBCommonConsult();
		DBCommonAlter dba=new DBCommonAlter();
		User b=dbc.getUser(mailTo,DBCommonConsult.REVIEWS);
		List<Review> l=b.getReviews();

		if(b instanceof Player)
		{

		}
		
		//TODO falta verificar si participaron en un evento juntos en el caso de que
		// se verifica el numero de eventos juntos y el numero de reviews... y por numero lo deja escribir o no
		l.add(new Review(""+(new Timestamp(( new java.util.Date()).getTime())),
				mailFrom, message, title, new Sport(sport.getName(),sport.getWraper()), calification, nameFrom,dbc.getUser(mailFrom, DBCommonConsult.LAZY),
				dbc.getUser(mailTo, DBCommonConsult.LAZY),false));

		b.setReviews(l);
		dba.saveUser(b,DBCommonAlter.UPDATE_USER);
		return true;
	}

	public List<Basic_User> getFollowers(String mail,String viewer) {
		DBCommonConsult dbc=new DBCommonConsult();
		User b=dbc.getUser(mail,DBCommonConsult.FOLLOW_FRIENDS);
		List<Basic_User> r=new ArrayList<Basic_User>();

		if(b instanceof Business || b instanceof Instructor)
		{
			for (User u : ((Business) b).getFollowers() ){
				r.add(new Basic_User(u.getName(), u.getMail(), u.getMiniPicture(), u.getCountry(), u.getCity().getName(),
						getFriendsInCommon(u.getMail(), viewer)));
			}
		}
		return r;
	}

	public boolean reportEvent(long eventId, String mailReporter, String message) {
		Event e=(new DBCommonConsult()).getEvent(eventId);
		List<Event_report> l=e.getReports();
		l.add(new Event_report(message, mailReporter,
				""+(new Timestamp(( new java.util.Date()).getTime()))));
		e.setReports(l);
		(new DBCommonAlter()).saveEvent(e,DBCommonAlter.UPDATE_EVENT);
		return true;
	}

	public Basic_User verifyUser(String mail, String password) {
		System.out.println("SignIn Intent: "+mail);
		User u=(new DBCommonConsult()).verifyUser(mail,password);
		
		if(u != null)
		{
			System.out.println("SignIn: "+u.getMail());
			return new Basic_User(u.getName(), u.getMail(),
					u.getMiniPicture(), u.getCountry(), u.getCity().getName(),null);
		}
		else return null;
	}

	public List<JSON_player> searchPlayers(String mail,JaxSport sport, String city,
			String country, boolean privacy, String dateFrom, String dateTo) {

		List<Player> l=(new DBCommonConsult()).getPlayers(mail,sport.getName(),city,country,privacy);
		if(l.isEmpty()||l==null)
		{
			 l=(new DBCommonConsult()).getPlayersWraper(mail,sport.getWraper(),city,country,privacy);
		}
		List<JSON_player> r=new ArrayList<JSON_player>();
		if(privacy)
		{
			for (Player p : l) {
				if(p.isActive()/*&&playerAvailableInDate(dateFrom,p)*/)
				{
					for (User u : p.getFriends()) {
						if(mail.equals(u.getMail()) )
						{
							r.add(new JSON_player(p.getName(), sportToString(p.getActive_sports()), 
									p.getGender(), p.getStartDate(), p.getEndDate(), p.getMail(), 
									convertSportCalifications(p.getSport_califications()),
									getFriendsInCommon(p.getMail(), mail),p.getActive_lat(),
									p.getActive_lng()));
						}
					}
				}
			}
		}
		else
		{
			for (Player p : l) {
				if(p.isActive()/*&&playerAvailableInDate(dateFrom,p)*/)
				{

					r.add(new JSON_player(p.getName(), sportToString(p.getActive_sports()), 
							p.getGender(), p.getStartDate(), p.getEndDate(), p.getMail(), 
							convertSportCalifications(p.getSport_califications()),
							getFriendsInCommon(p.getMail(), mail),p.getActive_lat(),
							p.getActive_lng()));
				}
			}
		}
		return r;
	}



	public List<JSON_business> searchBusiness(String mail,String city, String country,
			boolean privacy,JaxSport sport,String type) {
		List<Business> l=(new DBCommonConsult()).getBusiness(mail,city,country,privacy,sport.getName(),type);
		if(l.isEmpty()||l==null)
		{
			l=(new DBCommonConsult()).getBusinessWraper(mail,city,country,privacy,sport.getWraper(),type);
		}
		List<JSON_business> r=new ArrayList<JSON_business>();
		if(privacy)
		{
			for (Business p : l) {
				for (User u : p.getFollowers()) {
					if(mail.equals(u.getMail()))
					{
						r.add(new JSON_business(p.getName(), convertBranch(p.getBranshList()), 
								p.getType().getType(), p.getDiscounts().size()>0, p.getMail(),
								getFriendsInCommon(p.getMail(), mail).size()));
					}
				}

			}
		}
		else
		{
			for (Business p : l) {
				r.add(new JSON_business(p.getName(), convertBranch(p.getBranshList()), 
						p.getType().getType(), p.getDiscounts().size()>0, p.getMail(),
						getFriendsInCommon(p.getMail(), mail).size()));

			}
		}
		return r;
	}

	public List<JSON_instructor> searchCoaches(String mail,String sport, String city,
			String country, boolean privacy) {
		List<Instructor> l=(new DBCommonConsult()).getCoaches(mail,sport,city,country,privacy);
		List<JSON_instructor> r=new ArrayList<JSON_instructor>();
		if(privacy)
		{
			for (Instructor p : l) {
				for (User u : p.getFollowers()) {
					if(mail.equals(u.getMail()))
					{
						r.add(new JSON_instructor(p.getName(), sportToString(p.getSports_of_interest()),
								p.getGender(), p.getInstructor_type().getType(), p.getDiscounts().size()>0, p.getMail(),
								getFriendsInCommon(p.getMail(), mail),p.getLat1(),p.getLng1()
								,p.getLat2(),p.getLng2(),p.getLat3(),p.getLng3()));
					}
				}

			}
		}
		else
		{
			for (Instructor p : l) {
				r.add(new JSON_instructor(p.getName(), sportToString(p.getSports_of_interest()),
						p.getGender(), p.getInstructor_type().getType(), p.getDiscounts().size()>0, p.getMail(),
						getFriendsInCommon(p.getMail(), mail),p.getLat1(),p.getLng1()
						,p.getLat2(),p.getLng2(),p.getLat3(),p.getLng3()));

			}
		}
		return r;
	}

	public List<JSON_event> searchEvents(String mail,String sport, String city,
			String country, boolean privacy) {
		DBCommonConsult dbc=new DBCommonConsult();
		List<Event> l=dbc.getEvents(mail,sport,city,country,privacy);
		List<JSON_event> r=new ArrayList<JSON_event>();
		if(privacy)
		{
			for (Event p : l) { 
				User u=dbc.getUser(p.getOwnersMail(),DBCommonConsult.FOLLOW_FRIENDS);
				if(u instanceof Business)
				{
					for (User u2 :((Business) u).getFollowers()) {
						if(mail.equals(u2.getMail()))
						{
							r.add(new JSON_event(p.getTitle(), u2.getName(),
									p.getMiniPicture(), p.getAddress(),
									sportToString(p.getSports()), p.getStarting_date(),
									p.getEnding_date(),
									p.getOpenings(), p.getId(),null,p.getLat(),p.getLng(),
									p.getRegistered().size()));
						}
					}
				}
				else if(u instanceof Instructor)
				{
					for (User u2 :((Instructor) u).getFollowers()) {
						if(mail.equals(u2.getMail()))
						{
							r.add(new JSON_event(p.getTitle(), u2.getName(),
									p.getMiniPicture(), p.getAddress(),
									sportToString(p.getSports()), p.getStarting_date(),p.getEnding_date(),
									p.getOpenings(), p.getId(),null,p.getLat(),p.getLng(),
									p.getRegistered().size()));
						}
					}
				}
				if(u instanceof Player)
				{
					for (User u2 :((Player) u).getFriends()) {
						if(mail.equals(u2.getMail()))
						{
							r.add(new JSON_event(p.getTitle(), u2.getName(),
									p.getMiniPicture(), p.getAddress(),
									sportToString(p.getSports()), p.getStarting_date(),p.getEnding_date(),
									p.getOpenings(), p.getId(),getFriendsInCommon(u.getMail(), mail)
									,p.getLat(),p.getLng(),
									p.getRegistered().size()));
						}
					}
				}

			}
		}
		else
		{
			for (Event p : l) {
				r.add(new JSON_event(p.getTitle(),dbc.getUser(p.getOwnersMail(),DBCommonConsult.FOLLOW_FRIENDS)
						.getName(),
						p.getMiniPicture(), p.getAddress(),
						sportToString(p.getSports()), p.getStarting_date(),p.getEnding_date(),
						p.getOpenings(), p.getId(),
						getFriendsInCommon(p.getOwnersMail(), mail),p.getLat(),p.getLng(),
						p.getRegistered().size()));

			}
		}
		return r;
	}

	public List<Basic_User> searchUsers(String string,String viewer) {
		List<User> l=(new DBCommonConsult()).getUsers(string);
		List<Basic_User> r=new ArrayList<Basic_User>();
		for (User u : l) {
			r.add(new Basic_User(u.getName(), u.getMail(), u.getMiniPicture(),
					u.getCountry(), u.getCity().getName(),getFriendsInCommon(u.getMail(), viewer)));
		}
		return r;
	}

	public List<Basic_User> getUserFriends(String mail,String viewer) {
		DBCommonConsult dbc=new DBCommonConsult();
		List<Basic_User> r=new ArrayList<Basic_User>();
		User u =dbc.getUser(mail, DBCommonConsult.FOLLOW_FRIENDS);
		if(u instanceof Player)
		{
			for (Player p : ((Player) u).getFriends()) {
				r.add(new Basic_User(p.getName(), p.getMail(), p.getMiniPicture(),
						p.getCountry(), p.getCity().getName(),getFriendsInCommon(p.getMail(), viewer)));
			}
		}

		return r;
	}

	public Full_User getPlayerInfo(String mail,String viewer) {
		User u=(new DBCommonConsult()).getUser(mail, DBCommonConsult.FULL);

		if(u instanceof Player)
		{
			if(areFriends(mail,viewer))
			{
				//TODO el event history mas los eventos en los que esta inscrito
				return new Full_Player(u.getCountry(), u.getCity().getName(),
						u.getDescription(), u.getJoinDate(), u.getMail(),
						u.getPicture(), u.getName(), u.getRating(), u.getPhone(),
						u.getStatus(), u.getNotifications().size(), 
						convertBusinessToBasic(u.getFollowing_businesses()), 
						convertInstructorToBasic(u.getFollowing_instructors()), 
						convertEvents(u.getEvents(),viewer), convertReviews(u.getReviews(),viewer), 
						getUnreadMessages(u), ((Player) u).getBirthday(), ((Player) u).isPrivacy(),
						convertSportCalifications(((Player) u).getSport_califications()), 
						((Player) u).getFriend_applicants().size(), convertPlayers(((Player) u).getFriends(),viewer),
						sportToString(((Player) u).getActive_sports()), ((Player) u).getEvent_suggestions().size(),
						((Player) u).getGender(), u.getCarrier(),true,((Player) u).isActive(),
						getFriendsInCommon(mail, viewer),convertEvents(((Player) u).getEvent_history(),viewer)
						,((Player) u).getActive_lat(),((Player) u).getActive_lng());
			}
			else
			{
				return new Full_Player(u.getCountry(), u.getCity().getName(),
						"", u.getJoinDate(), u.getMail(),
						u.getPicture(), u.getName(), -1, "",
						u.getStatus(), 0, 
						null, 
						null, 
						convertEvents(u.getEvents(),viewer),null, 
						-1, "", false,
						null, 
						-1, convertPlayers(((Player) u).getFriends(),viewer),
						sportToString(((Player) u).getActive_sports()), -1,
						((Player) u).getGender(),"",false,((Player) u).isActive(),
						getFriendsInCommon(mail, viewer),null,0,0);
			}
		}
		return null;
	}

	public Full_User getCoachInfo(String mail,String viewer) {
		User u=(new DBCommonConsult()).getUser(mail, DBCommonConsult.FULL);

		if(u instanceof Instructor)
		{
			return new Full_Instructor(u.getCountry(), u.getCity().getName(), u.getDescription(), u.getJoinDate(),
					u.getMail(), u.getPicture(), u.getName(), u.getRating(), u.getPhone(), u.getStatus(), u.getNotifications().size(),
					convertBusinessToBasic(u.getFollowing_businesses()), convertInstructorToBasic(u.getFollowing_instructors()),
					convertEvents(u.getEvents(),viewer),convertReviews(u.getReviews(), viewer), getUnreadMessages(u), 
					((Instructor) u).getExperience_years(), ((Instructor) u).getBirthday(),((Instructor) u).getGender(),
					convertUsers(((Instructor) u).getFollowers(),viewer), ((Instructor) u).getInstructor_type().getType(),
					convertPlayers(((Instructor) u).getClients(),viewer), convertPlayers(((Instructor) u).getClient_applicants(),viewer),
					sportToString(u.getSports_of_interest()), u.getCarrier(), viewerIsFollowing(viewer,u), 
					getFriendsFollowing(viewer,u),((Instructor) u).getDiscounts().size()>0?true:false,
							convertDiscounts(((Instructor) u).getDiscounts()),
							((Instructor) u).getLat1(),((Instructor) u).getLng1(),
							((Instructor) u).getLat2(),((Instructor) u).getLng2(),
							((Instructor) u).getLat3(),((Instructor) u).getLng3());

		}
		return null;
	}

	public Full_User getBusinessInfo(String mail,String viewer) {
		User u=(new DBCommonConsult()).getUser(mail, DBCommonConsult.FULL);

		if(u instanceof Business)
		{
			return new Full_Business(u.getCountry(), u.getCity().getName(), u.getDescription(), u.getJoinDate(),
					u.getMail(), u.getPicture(), u.getName(), u.getRating(), u.getPhone(), u.getStatus(),
					u.getNotifications().size(), convertBusinessToBasic(u.getFollowing_businesses()),
					convertInstructorToBasic(u.getFollowing_instructors()), convertEvents(u.getEvents(),viewer),
					convertReviews(u.getReviews(), viewer), getUnreadMessages(u),  
					((Business) u).getDiscounts().size()>0?true:false, 
							convertDiscounts(((Business) u).getDiscounts()), 
							((Business) u).getType().getType(), convertUsers(((Business) u).getFollowers(), viewer),
							sportToString(u.getSports_of_interest()),u.getCarrier(), viewerIsFollowing(viewer, u), 
							getFriendsFollowing(viewer, u),convertBranch(((Business) u).getBranshList()));
		}
		return null;
	}

	public Event_Info createEvent(String mailOwner,String nameOwner, String title,
			String address, String description, String ending_date,
			String starting_date, double lat, double lng, String miniPicture,
			String picture, int openings, boolean privacy, List<JaxCommonClases.JaxSport> sports,
			String city,String country) {
		Event e=new Event(mailOwner,nameOwner, address, description, ending_date, lat, lng, 
				miniPicture, openings, picture, privacy, starting_date, title,
				new City(city, country),convertJaxSportToSport(sports));
		(new DBCommonAlter()).saveEvent(e,DBCommonAlter.SAVE_EVENT);
		return new Event_Info(e.getId(), address, description,
				ending_date, lat, lng, openings, picture, privacy,
				starting_date, title,new ArrayList<JSON_comment>(), 
				convertJaxSportToString(sports), city, 
				new ArrayList<Basic_User>(),new ArrayList<Basic_User>(),country,mailOwner,nameOwner,
				getFriendsRegisteredInEvent(mailOwner, e));

	}

	
	
	public List<JSON_event> getUserEvents(String mail,String viewer) {
		User u=(new DBCommonConsult()).getUser(mail, DBCommonConsult.EVENTS);
		List<JSON_event> r=new ArrayList<JSON_event>();
		for (Event e : u.getEvents()) {
			r.add(new JSON_event(e.getTitle(), e.getOwnersName(), e.getMiniPicture(),
					e.getAddress(), sportToString(e.getSports()), e.getStarting_date(),e.getEnding_date(), 
					e.getOpenings(), e.getId(), getFriendsInCommon(e.getOwnersMail(), viewer),
					e.getLat(),e.getLng(),
					e.getRegistered().size()));
		}
		return r;
	}

	public List<JSON_notification> getNotifications(String mail) {
		// TODO Auto-generated method stub
		return null;
	}

	public boolean deleteConversation(String mailUser, String mailWith) {
		DBCommonConsult dbc=new DBCommonConsult();
		User us=dbc.getUser(mailUser,DBCommonConsult.CONVERSATIONS);
		List<Message> sent=us.getSent();
		List<Message> recieved=us.getReceived();

		for (Message message : recieved) {
			if(message.getMailFrom().equals(mailWith))
			{
				recieved.remove(message);
			}
		}
		for (Message message : sent) {

			if(message.getMailFrom().equals(mailWith))
			{
				sent.remove(message);
			}
		}
		(new DBCommonAlter()).saveUser(us, DBCommonAlter.UPDATE_USER);
		return true;
	}

	public boolean deleteMessage(String mailUser, long messageId,String mailWriter) {
		DBCommonConsult dbc=new DBCommonConsult();
		User us=dbc.getUser(mailUser,DBCommonConsult.CONVERSATIONS);
		List<Message> sent=us.getSent();
		List<Message> recieved=us.getReceived();
		boolean r=false;
		if(mailWriter.equals(mailUser)){
			for (Message message : sent) {

				if(message.getId()==messageId)
				{
					sent.remove(message);
					r=true;
				}
			}
		}
		else
		{
			for (Message message : recieved) {
				if(message.getId()==messageId && message.getMailFrom().equals(mailWriter))
				{
					recieved.remove(message);
					r=true;
				}
			}
		}

		(new DBCommonAlter()).saveUser(us, DBCommonAlter.UPDATE_USER);
		return r;
	}

	private List<JSON_Discount> convertDiscounts(List<Discount> discounts) {
		List<JSON_Discount> r=new ArrayList<JSON_Discount>();
		for (Discount d : discounts) {
			r.add(new JSON_Discount(d.getId(), d.getDescription(), d.getDate()));
		}
		return r;
	
	}

	private List<Basic_User> convertUsers(List<User> users,String viewer) {
		List<Basic_User> r=new ArrayList<Basic_User>();
		for (User u : users) {
			r.add(new Basic_User(u.getName(), u.getMail(), u.getMiniPicture(), u.getCountry(), u.getCity().getName(),
					getFriendsInCommon(u.getMail(), viewer)));
		}
		return r;
	}

	private int getFriendsFollowing(String viewer, User u) {
		int i=0;
		User vie=(new DBCommonConsult()).getUser(viewer, DBCommonConsult.FOLLOW_FRIENDS);
		if((u instanceof Business || u instanceof Instructor)&& vie instanceof Player)
		{
			for (User us : ((Business) u).getFollowers()) 
			{
				int imin=0;
				List<Player> f=((Player) vie).getFriends();
				int imax=f.size()-1;
				while (imax >= imin)
				{
					/* calculate the midpoint for roughly equal partition */
					int imid = imax+imin/2;
	
					// determine which subarray to search
					if (f.get(imid).getMail().compareTo(us.getMail()) > 0 )
						// change min index to search upper subarray
						imin = imid + 1;
					else if (f.get(imid).getMail().compareTo(us.getMail()) < 0)
						// change max index to search lower subarray
						imax = imid - 1;
					else
						i++;
				}
			}
		}
		return i;
	}

	private boolean viewerIsFollowing(String viewer, User u) {
		if(u instanceof Business || u instanceof Instructor)
		{
			for (User us : ((Business) u).getFollowers()) {
				if(us.getMail().equalsIgnoreCase(viewer))
				{
					return true;
				}
			}
		}
		return false;
	}

	private boolean areFriends(String mail, String viewer) {
		Player u1=(new DBCommonConsult()).getPlayer(mail);
		if(u1!=null)
		{
			for (User u : u1.getFriends()) {
				if(u.getMail().equals(viewer))
				{
					return true;
				}
			}
		}
		return false;
	}

	private List<JSON_Branch> convertBranch(List<Branch> branshList) {
		List<JSON_Branch> r=new ArrayList<JSON_Branch>();
		for (Branch b : branshList) {
			r.add(new JSON_Branch(b.getName(), b.getAddress(), b.getCountry(), b.getOpening_hours(),
					b.getEmailBranch(), b.getPhoneBranch(), b.getMailBusiness(), b.getCity().getName(),
					b.getLat(), b.getLng(),sportToString((b.getSports()))));
		}
		return r;
	}

	private List<JSON_sport_calification> convertSportCalifications(
			List<Sport_calification> sport_califications) {
		List<JSON_sport_calification> r=new ArrayList<JSON_sport_calification>();
		for (Sport_calification sc : sport_califications) {
			r.add(new JSON_sport_calification(sc.getSport().getName(), sc.getAverage_calification()));
		}
		return r;
	}

	private List<String> sportToString(List<Sport> active_sports) {
		List<String> r=new ArrayList<String>();
		for (Sport sport : active_sports) {
			r.add(""+sport.getName()+"/"+sport.getWraper());
		}
		return r;
	}

	private List<Basic_User> convertBusinessToBasic(
			List<Business> following_businesses) {
		List<Basic_User> r=new ArrayList<Basic_User>();
		for (Business b : following_businesses) {
			r.add(new Basic_User(b.getName(), b.getMail(), b.getMiniPicture(), b.getCountry(), 
					b.getCity().getName(), null));
		}
		return r;
	}

	private int getUnreadMessages(User u) {
		// TODO Auto-generated method stub
		return 0;
	}

	private List<Basic_User> convertInstructorToBasic(
			List<Instructor> following_instructors) {
		List<Basic_User> r=new ArrayList<Basic_User>();
		for (Instructor b : following_instructors) {
			r.add(new Basic_User(b.getName(), b.getMail(), b.getMiniPicture(), b.getCountry(), b.getCity().getName(),null));
		}
		return r;
	}

	private List<Event_Info> convertEvents(List<Event> events,String viewer) {
		List<Event_Info> r=new ArrayList<Event_Info>();
		for (Event e : events) {
			r.add(new Event_Info(e.getId(), e.getAddress(), e.getDescription(), 
					e.getEnding_date(), e.getLat(), e.getLng(), e.getOpenings(),
					e.getPicture(), e.isPrivacy(), e.getStarting_date(), e.getTitle(),
					convertComments(e.getComments()), sportToString(e.getSports()),
					e.getCity().getName(), convertPlayers(e.getRegistered(), viewer),
					convertPlayers(e.getApplicants(), viewer), e.getCity().getCountry(),
					e.getOwnersMail(), e.getOwnersName(),getFriendsRegisteredInEvent(viewer, e)));
		}
		return r;
	}

	private List<Basic_User> convertPlayers(List<Player> players,String viewer) {

		List<Basic_User> r=new ArrayList<Basic_User>();
		for (Player b : players) {
			r.add(new Basic_User(b.getName(), b.getMail(), b.getMiniPicture(), b.getCountry(), b.getCity().getName()
					,getFriendsInCommon(b.getMail(), viewer)));
		}
		return r;
	}

	private List<JSON_comment> convertComments(List<Comment> comments) {
		List<JSON_comment> r=new ArrayList<JSON_comment>();
		for (Comment c : comments) {
			User u=new DBCommonConsult().getUser(c.getMailFrom(), DBCommonConsult.LAZY);
			r.add(new JSON_comment(c.getDate(), c.getMailFrom(), c.getMessage(), c.getTitle(),
					u.getMiniPicture(),u.getName()));
		}
		return r;
	}

	private List<JSON_review> convertReviews(List<Review> reviews,String viewer) {

		List<JSON_review> r=new ArrayList<JSON_review>();
		for (Review re: reviews) {
			r.add(new JSON_review(re.getMessage(), re.getDate(), re.getMailFrom(),
					re.getNameFrom(), re.getTitle(), re.getSport().getName(),
					(re.getMailFrom().equals(viewer)?true:false),re.getId()));	
		}
		return r;
	}

	private boolean playerAvailableInDate(String date, Player p) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");

		try {

			java.util.Date thisdated = dateFormat.parse(date);


			java.sql.Timestamp thisdate = new java.sql.Timestamp(thisdated.getTime());
			java.sql.Timestamp sdate= new java.sql.Timestamp(dateFormat.parse(p.getStartDate()).getTime());
			java.sql.Timestamp edate = new java.sql.Timestamp(dateFormat.parse(p.getEndDate()).getTime());
			if(thisdate.after(sdate) && thisdate.before(edate))
			{
				return true;
			}

			else
			{
				return false;
			}
		} catch (ParseException e) {

			e.printStackTrace();
			return false;
		}
	}
	private List<Basic_User> getFriendsRegisteredInEvent(String viewer,Event e) {
		List<Basic_User> r=new ArrayList<Basic_User>();
		User u=new DBCommonConsult().getUser(viewer, DBCommonConsult.FOLLOW_FRIENDS);
		if(u instanceof Player)
		{
			for (Player us : e.getRegistered()) {
				int imin=0;
				List<Player> f= ((Player) u).getFriends();
				int imax=f.size()-1;
				while (imax >= imin)
				{
					/* calculate the midpoint for roughly equal partition */
					int imid = imax+imin/2;

					// determine which subarray to search
					if (f.get(imid).getMail().compareTo(us.getMail()) > 0 )
						// change min index to search upper subarray
						imin = imid + 1;
					else if (f.get(imid).getMail().compareTo(us.getMail()) < 0)
						// change max index to search lower subarray
						imax = imid - 1;
					else
					{
						r.add(new Basic_User(us.getName(),
								us.getMail(), us.getMiniPicture(), us.getCountry(), us.getCity().getName(),
								getFriendsInCommon(us.getMail(), viewer)));
					}
				}
			}
		}
		return r;
		
	}

	private List<CommonUser> getFriendsInCommon(String mail,String viewer) {
		DBCommonConsult dbc=new DBCommonConsult();

		Player a = dbc.getPlayer(mail);
		Player v = dbc.getPlayer(viewer);
		List<CommonUser> fic = new ArrayList<CommonUser>();
		if(a !=null && v !=null)
		{
			for (Player p1 : a.getFriends()) 
			{
				int imin=0;
				List<Player> f= v.getFriends();
				int imax=f.size()-1;
				while (imax >= imin)
				{
					/* calculate the midpoint for roughly equal partition */
					int imid = imax+imin/2;

					// determine which subarray to search
					if (f.get(imid).getMail().compareTo(p1.getMail()) > 0 )
						// change min index to search upper subarray
						imin = imid + 1;
					else if (f.get(imid).getMail().compareTo(p1.getMail()) < 0)
						// change max index to search lower subarray
						imax = imid - 1;
					else
					{
						CommonUser c = new CommonUser(p1.getName(), p1.getMail(), p1.getMiniPicture(),	p1.getCountry(), p1.getCity().getName());
						fic.add(c);
					}
				}
			}
		}
		return fic;
	}
	


	private List<Sport> convertJaxSportToSport(List<JaxCommonClases.JaxSport> sports) {
		// TODO Auto-generated method stub
		return null;
	}
	private List<String> convertJaxSportToString(List<JaxCommonClases.JaxSport> sports) {
		// TODO Auto-generated method stub
		return null;
	}



	public boolean deleteReview(long id, String mailWriter, String mailTo) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean deleteEvent(long id, String mailSession) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean deleteDiscount(long id, String mailSession) {
		// TODO Auto-generated method stub
		return false;
	}

	public List<Basic_User> generalSearch(String string, String viewer) {
		//TODO falta retornar eventos tambien
		List<User> l=(new DBCommonConsult()).getUsers(string);
		List<Basic_User> r=new ArrayList<Basic_User>();
		for (User u : l) {
			r.add(new Basic_User(u.getName(), u.getMail(), u.getMiniPicture(),
					u.getCountry(), u.getCity().getName(),getFriendsInCommon(u.getMail(), viewer)));
		}
		return r;
	}

	public String getUsersType(String mail) {
		User u=new DBCommonConsult().getUser(mail, DBCommonConsult.LAZY);
		if(u instanceof Business)
		{
			return SplitterConstants.Business;
		}
		else if(u instanceof Instructor)
		{
			return SplitterConstants.Instructor;
		}
		else
		{
			return SplitterConstants.Player;
		}
	}

	public boolean writeFeedback(String mail, String subject, String comment) {
		Feedback f=new Feedback(mail, subject, comment);
		return new DBCommonAlter().saveFeedback(f);
	}

	public boolean writeCommentToEvent(long eventId, String mail, String message) {
		Event e=new DBCommonConsult().getEvent(eventId);
		List<Comment> c=e.getComments();
		c.add(new Comment(""+(new Timestamp(( new java.util.Date()).getTime())), mail, message, ""));
		return new DBCommonAlter().saveEvent(e, DBCommonAlter.UPDATE_EVENT);
	}

	public boolean sendEventSuggestion(String mailSender, String mailTo,
			long eventId) {
		// TODO Auto-generated method stub
		return false;
	}

}
